#include "stdafx.h"
#include "EventUtil.h"

EventScheduler::EventScheduler(EventChannel* channel)
{
	m_Channel	= channel;
	m_LocalTick = 0;
}

EventScheduler::~EventScheduler()
{
	for (ScheduleQueue::iterator itr = m_Queue.begin(), end = m_Queue.end(); itr != end; ++itr)
	{
		if (itr->Event)
			delete itr->Event;
	}
}

void EventScheduler::StepTick()
{
	while (!m_Queue.empty())
	{
		const Entry& top = m_Queue.top();

		if (top.Tick > m_LocalTick)
			break;

		Event* evt = top.Event;
		IEventHandler* to = top.To;

		m_Queue.pop();
		// warning : 'top' variable is not valid anymore.

		if (evt == NULL)
			continue;

		if (to)
		{
			m_Channel->Send(to, evt);
		}
		else
		{
			m_Channel->Broadcast(evt);
		}

		delete evt;
	}

	++m_LocalTick;
}

void EventScheduler::ScheduleAfter(uint tickAfter, Event* evt, IEventHandler* to)
{
	Entry e;
	e.Tick = m_LocalTick + tickAfter;
	e.To = to;

	// allocate memory for the event
	e.Event = evt->GetInfo()->Create();

	// copy event
	memcpy(e.Event, evt, evt->GetInfo()->GetNumBytes());

	m_Queue.push(e);
}

void EventScheduler::CancleFor(IEventHandler* handler)
{
	for (ScheduleQueue::iterator itr = m_Queue.begin(), end = m_Queue.end(); itr != end; ++itr)
	{
		if (itr->To == handler)
		{
			itr->Event	= NULL;
			itr->To		= NULL;
		}
	}
}

